/*
 * @Description: 生成 uniapp form
 * @Author: DHL
 * @Date: 2022-01-30 14:20:12
 * @LastEditors: DHL
 * @LastEditTime: 2023-01-08 21:21:40
 */

import { firstToUpperCase, firstToLowerCase, getVueDefaultValue } from '../../utils/codeGenUtils'

export function createUniappForm(codeGenConfig: any) {
  const classNameFirstToUpperCase = firstToUpperCase(codeGenConfig.className)
  const classNameFirstToLowerCase = firstToLowerCase(codeGenConfig.className)
  const apiPath = codeGenConfig.pagesApiPath

  return `
<!--
* @Description: ${codeGenConfig.genName} - 表单
* @Author: ${codeGenConfig.genAuthor}
* @Date: ${codeGenConfig.createData}
* @LastEditors: ${codeGenConfig.genAuthor}
* @LastEditTime: ${codeGenConfig.createData}
-->
<template>
  <view class="tw-wrap">
    <tw-footer>
      <view class="form-wrap">
        <uni-forms ref="formRef" :modelValue="dbForm" :rules="rules" label-width="120" label-position="top" border>
        ${getForm(codeGenConfig.optionsJson.columns)}
          <uni-forms-item label="附件" name="fileIds">
            <tw-upload
              ref="uploadRef"
              v-model="dbForm.fileIds"
              :action="action"
              :maxNum="10"
              :bizId="dbForm.id"
              bizType="${classNameFirstToLowerCase}"
              bizTypeName="${codeGenConfig.genName}附件"
              :params="{ folder: '${classNameFirstToLowerCase}' }"
            ></tw-upload>
          </uni-forms-item>
        </uni-forms>
      </view>

      <template #footer>
        <view class="action" v-if="!isView">
          <uv-button
            type="primary"
            size="normal"
            shape="circle"
            text="提交"
            @click="handleSubmit"
          ></uv-button>
        </view>
        <uv-safe-bottom></uv-safe-bottom>
      </template>
    </tw-footer>
  </view>
</template>

<script lang="ts" setup>
  import { onLoad } from '@dcloudio/uni-app'
  import { getCurrentInstance, reactive, ref, computed } from 'vue'
  import { assign } from 'lodash-es'
  import { isNotEmpty } from '@/utils/isUtils'
  import { api${classNameFirstToUpperCase}GetById, api${classNameFirstToUpperCase}Save, api${classNameFirstToUpperCase}UpdateById } from '@/${apiPath}/${classNameFirstToLowerCase}'


  //////////////////////////////////////////////////
  // 生命周期
  //////////////////////////////////////////////////
  const instance: any = getCurrentInstance()?.proxy
  const eventChannel = instance?.getOpenerEventChannel()

  onLoad((options) => {
    action.value = options?.action || 'view'
    dbForm.id = options?.id || ''
    if (isNotEmpty(dbForm.id)) {
      handleGetById()
    }
  })

  //////////////////////////////////////////////////
  // 属性
  //////////////////////////////////////////////////
  /**
   * 操作标识
   */
  const action = ref('view')

  /**
   * 表单对象
   */
  const formRef = ref()

  /**
   * 是否为显示模式
   */
  const isView = computed(() => {
    return action.value == 'view'
  })
  
  /**
   * 表单数据
   */
  const dbForm = reactive({
  ${getField(codeGenConfig.optionsJson.columns)}
  })

  /**
   * 校验规则
   */
  const rules = reactive({
    ${getRules(codeGenConfig.optionsJson.columns)}
  })


  //////////////////////////////////////////////////
  // 函数
  //////////////////////////////////////////////////
  /**
   * 根据主键查询详情
   */
  function handleGetById() {
    uni.showLoading({
      title: '加载中...'
    })
    api${classNameFirstToUpperCase}GetById(dbForm.id)
      .then((result) => {
        if (result?.success) {
          assign(dbForm, result.data)
        } else {
          uni.showToast({
            title: result?.message,
            icon: 'none'
          })
        }
      })
      .finally(() => {
        uni.hideLoading()
      })
  }

  /**
   * 提交表单
   */
  function handleSubmit() {
    formRef.value
      .validate()
      .then((result: any) => {
        if (action.value == 'add') {
          addFun()
        } else if (action.value == 'edit') {
          editFun()
        }
      })
      .catch((err: any) => {
        console.log('表单错误信息：', err)
      })
  }

  /**
   * 新增
   */
  function addFun() {
    uni.showLoading({
      title: '提交中...'
    })

    api${classNameFirstToUpperCase}Save(dbForm)
      .then((result) => {
        uni.showToast({
          title: result?.message,
          icon: 'none'
        })

        if (result?.success) {
          uni.navigateBack({
            delta: 1,
            success: () => {
              eventChannel.emit('addEvent', {})
            }
          })
        }
      })
      .catch(() => {})
      .finally(() => {
        uni.hideLoading()
      })
  }

  /**
   * 编辑
   * @returns
   */
  function editFun() {
    uni.showLoading({
      title: '提交中...'
    })

    api${classNameFirstToUpperCase}UpdateById(dbForm)
      .then((result) => {
        uni.showToast({
          title: result?.message,
          icon: 'none'
        })

        if (result?.success) {
          uni.navigateBack({
            delta: 1,
            success: () => {
              eventChannel.emit('editEvent', {})
            }
          })
        }
      })
      .catch(() => {})
      .finally(() => {
        uni.hideLoading()
      })
  }
</script>

<style lang="scss" scoped>
  .action {
    padding: 20rpx 60rpx;
    background-color: #ffffff;
  }
</style>
`
}

/**
 * 获取字段
 * @param columns
 */
function getField(columns: any) {
  let field: Array<string> = []

  columns.forEach((item: any) => {
    if (item.form) {
      field.push(`  ${item.javaField}: ${getVueDefaultValue(item)},  // ${item.javaComment}
        `)
    }
  })

  field.push(`fileIds: '',  // 附件
      `)

  return field.join('')
}

/**
 * 获取表单
 * @param columns
 */
function getForm(columns: any) {
  let rtn: Array<string> = []

  columns.forEach((item: any) => {
    if (item.form && item.columnKey !== '1') {
      rtn.push(
        `
          <uni-forms-item label="${item.javaComment}" name="${item.javaField}" ${
          item.required ? 'required' : ''
        }>
            ${getComponent(item)}
          </uni-forms-item>
    `
      )
    }
  })
  return rtn.join('')
}

/**
 * 表单组件
 * @param item
 * @returns
 */
function getComponent(item: any) {
  let rtn: Array<string> = []

  switch (item.componentType) {
    case 'input':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <uni-easyinput v-else v-model="dbForm.${item.javaField}" placeholder="请输入${item.javaComment}" :inputBorder="false" />`
      )
      break
    case 'textarea':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <uni-easyinput v-else type="textarea" autoHeight v-model="dbForm.${item.javaField}" placeholder="请输入${item.javaComment}"  />`
      )
      break
    case 'select':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <uni-data-select v-else v-model="dbForm.${item.javaField}" placeholder="请选择${item.javaComment}" :localdata="[{ value: 0, text: '开发实现' }]"></uni-data-select>`
      )
      break
    case 'inputNumber':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <uni-easyinput v-else type="digit" autoHeight v-model="dbForm.${item.javaField}" placeholder="请输入${item.javaComment}" :inputBorder="false" />`
      )
      break
    case 'radio':
      rtn.push(
        `<uni-data-checkbox v-model="dbForm.${item.javaField}" :localdata="[{text:'男', value:0}, {text:'女', value: 1}]"></uni-data-checkbox>`
      )
      break
    case 'checkbox':
      rtn.push(
        `<uni-data-checkbox multiple v-model="dbForm.${item.javaField}" :localdata="[{text:'男', value:0}, {text:'女', value: 1}]"></uni-data-checkbox>`
      )
      break
    case 'datePicker':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <tw-date v-else v-model="dbForm.${item.javaField}" placeholder="请选择${item.javaComment}"></tw-date>`
      )
      break
    case 'dateTimePicker':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <uni-datetime-picker v-else type="datetime" return-type="string" v-model="dbForm.${item.javaField}" placeholder="请选择${item.javaComment}" :border="false"/>`
      )
      break
    case 'timePicker':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <tw-date-time v-else v-model="dbForm.${item.javaField}" placeholder="请选择${item.javaComment}"></tw-date-time>`
      )
      break
    case 'timeSelect':
      rtn.push(
        `<text v-if="isView">{{ dbForm.${item.javaField} }}</text>
            <tw-date-time v-else v-model="dbForm.${item.javaField}" placeholder="请选择${item.javaComment}"></tw-date-time>`
      )
      break
    case 'switch':
      rtn.push()
      break
    case 'upload':
      rtn.push(``)
      break
    case 'dataDic':
      rtn.push(
        `<tw-dic-name v-if="isView" dicKey="${item.dataDic}" :dicValue="dbForm.${item.javaField}"></tw-dic-name>
          <tw-dic v-else v-model="dbForm.${item.javaField}" dicKey="${item.dataDic}" placeholder="请选择${item.javaComment}"></tw-dic>`
      )
      break
    case 'money':
      rtn.push()
      break
    default:
      break
  }
  return rtn.join('')
}

/**
 * 获取表单验证
 * @param columns
 */
function getRules(columns: any) {
  let field: Array<string> = []

  let fieldArray: any[] = []

  columns.forEach((item: any) => {
    if (item.form) {
      fieldArray.push(item)
    }
  })

  for (let i = 0; i < fieldArray.length; i++) {
    const item = fieldArray[i]

    if (i === fieldArray.length - 1) {
      field.push(`${getRulesItem(item)}`)
    } else {
      if (item.required) {
        field.push(`${getRulesItem(item)},
      `)
      }
    }
  }

  return field.join('')
}

function getRulesItem(item: any) {
  let rtn = ''

  let errorMsg = ''

  switch (item.componentType) {
    case 'select':
      errorMsg = '请选择'
      break
    case 'radio':
      errorMsg = '请选择'
      break
    case 'checkbox':
      errorMsg = '请选择'
      break
    case 'datePicker':
      errorMsg = '请选择'
      break
    case 'dateTimePicker':
      errorMsg = '请选择'
      break
    case 'timePicker':
      errorMsg = '请选择'
      break
    case 'timeSelect':
      errorMsg = '请选择'
      break
    case 'switch':
      errorMsg = '请选择'
      break
    case 'upload':
      errorMsg = '请上传'
      break
    case 'dataDic':
      errorMsg = '请选择'
      break
    default:
      errorMsg = '请输入'
      break
  }

  errorMsg += item.javaComment

  let rules: Array<string> = []
  if (item.required) {
    rules.push(`  {
          required: true,
          errorMessage: '${errorMsg}'
        }`)
  }

  if (item.charMaxLength) {
    rules.push(`  {
          maxLength: ${item.charMaxLength},
          message: '最多可输入${item.charMaxLength}个字符'
        }`)
  }

  rtn = `${item.javaField}: {
      rules: [
        ${rules.join(',')}
      ]
  }`

  return rtn
}
